package cn.jx.cjm.security.support;

import cn.jx.cjm.security.common.bean.CjmGrantedAuthority;
import cn.jx.cjm.security.entity.SysPermission;
import cn.jx.cjm.security.common.bean.TokenUser;
import cn.jx.cjm.security.common.constant.SecuritySystemConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Rbac权限校验
 *
 * @author 陈加敏
 * @since 2019/7/15 14:25
 */
@Service
public class RbacAuthorityService {


    @Autowired
    private SysPermissionSupportService sysPermissionSupportService;
    /**
     * URL匹配工具
     */
    private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher();
    /**
     * 权限判断
     * @param request .
     * @param authentication .
     * @return .
     */
    public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
        Object userInfo = authentication.getPrincipal();

        //用户信息判断 , 当token违背携带时出现此情况
        if (!(userInfo instanceof UserDetails)) {
            return false;
        }
        TokenUser tokenUser = (TokenUser)userInfo;
        //超级管理员判断
        if(SecuritySystemConstants.SUPER_ADMIN_ID.equals(tokenUser.getId())){
            return true;
        }

        List<CjmGrantedAuthority> authorities = tokenUser.getAuthorities();
        //角色为空判断
        if (CollectionUtils.isEmpty(authorities)) {
            return false;
        }

        //获取角色权限
        Set<Integer> sysRoleIdSet = authorities.stream().map(CjmGrantedAuthority::getSysRoleId).collect(Collectors.toSet());
        List<SysPermission> sysPermissionList = sysPermissionSupportService.getPermissionByRoles(sysRoleIdSet);

        //请求uri
        String requestUri = request.getRequestURI();
        String requestMethod = request.getMethod();
        //判断匹配用户权限
        for (SysPermission sysPermission : sysPermissionList) {
            String permissionPath = sysPermission.getAuthorityPath();
            String permissionMethod = sysPermission.getAuthorityMethod();
            if (!StringUtils.isEmpty(permissionPath)) {
                //uri匹配
                if (ANT_PATH_MATCHER.match(permissionPath, requestUri) && requestMethod.equalsIgnoreCase(permissionMethod)) {
                    return true;
                }
            }
        }
        return false;
    }
}
